import serial
import json
import os
CACHE_PATH = os.path.join(os.path.dirname(__file__), 'cache', 'config.json')

DEFULT_CONF = {
    "serial_port": "",
}
# 尝试加载配置文件，加载失败的话使用默认配置，并且把默认配置载入到配置文件
def load_config():
    global CACHE_PATH, DEFULT_CONF
    try:
        with open(CACHE_PATH, 'r') as f:
            conf = json.load(f)
        DEFULT_CONF.update(conf)
    except Exception as e:
        conf = DEFULT_CONF
        with open(CACHE_PATH, 'w') as f:
            json.dump(conf, f)

# 尝试对串口发起连接，并且检查连接情况，直接返回中文字符串代表连接情况
# 尝试完毕后关闭串口，以防占用
def check_serial_port():
    port = DEFULT_CONF['serial_port']
    try:
        with serial.Serial(port, 115200, timeout=1) as ser:
            if ser.is_open:
                return f"端口{port} 连接成功"
            else:
                return f"端口{port} 连接失败"
    except serial.SerialException as e:
        return f"端口{port} 连接失败: {str(e)}"

def send_command(command):
    port = DEFULT_CONF['serial_port']
    command = command.strip() + "\r\n"
    try:
        with serial.Serial(port, 115200, timeout=0) as ser:
            if ser.is_open:
                ser.write(command.encode())
                ser.flush()
                ret =  ser.readline().decode()
                if ret:
                    return ret
                return "已发送，无返回"
    except serial.SerialException as e:
        print(f"连接失败: {str(e)}")
        return f"连接失败: {str(e)}"

def send_and_get(command)->float:
    port = DEFULT_CONF['serial_port']
    command = command.strip() + "\r\n"
    try:
        with serial.Serial(port, 115200, timeout=0.1) as ser:
            if ser.is_open:
                ser.write(command.encode())
                ser.flush()
                ret =  ser.readline().decode().strip().split()
                if ret:
                    return float(ret[-1])
                # print("None feedback")
                return -1.00
    except serial.SerialException as e:
        print(f"连接失败: {str(e)}")
        return -1.0

class HardwareController:
    @staticmethod
    def set_motor_speed(value: int):
        """磁力搅拌器转速设置，范围-1000~1000，命令：Motor value"""
        return send_command(f"Motor {value}")

    @staticmethod
    def set_max_pressure(value: int):
        """增压泵最大压力设置，范围0~4200，命令：setMaxPres value"""
        return send_command(f"setMaxPres {value}")

    @staticmethod
    def set_min_pressure(value: int):
        """增压泵最小压力设置，范围0~4200，命令：setMinPres value"""
        return send_command(f"setMinPres {value}")

    @staticmethod
    def clear_pressure():
        """压力清零，命令：clearPres 0"""
        return send_command("clearPres 0")

    @staticmethod
    def get_max_pressure():
        """获取最大压力，命令：getMaxPres 1，返回：MaxPres value"""
        return send_command("getMaxPres 1")

    @staticmethod
    def get_min_pressure():
        """获取最小压力，命令：getMinPres 1，返回：MinPres value"""
        return send_command("getMinPres 1")

    @staticmethod
    def set_traffic(value: int):
        """设置流量，范围1~9999，命令：setTraffic value"""
        return send_command(f"setTraffic {value}")

    @staticmethod
    def get_traffic():
        """获取流量，命令：getTraffic 1，返回：Traffic value"""
        return send_command("getTraffic 1")

    @staticmethod
    def start_pump():
        """启动泵，命令：startPump 1"""
        return send_command("startPump 1")

    @staticmethod
    def stop_pump():
        """停止泵，命令：stopPump 1"""
        return send_command("stopPump 1")

    @staticmethod
    def get_pump_state():
        """读取泵状态，命令：getPumpState 1，返回：PumpState 0/1"""
        return send_command("getPumpState 1")

    @staticmethod
    def get_pressure():
        """读取泵压力，命令：getPres 1，返回：pres value"""
        return send_command("getPres 1")

    @staticmethod
    def start_pressure_sample(value: int):
        """开启泵压力采样，范围0~100（采样间隔为value*50ms），命令：startPresSample value"""
        return send_command(f"startPresSample {value}")

    @staticmethod
    def set_valve1(value: int):
        """进气阀开关，0/1，命令：Valve1 value"""
        return send_command(f"Valve1 {value}")

    @staticmethod
    def set_valve2(value: int):
        """出气阀开关，范围0~255，命令：Valve2 value"""
        return send_command(f"Valve2 {value}")

    @staticmethod
    def set_alarm(value: int):
        """报警器开关，0/1，命令：Alarm value"""
        return send_command(f"Alarm {value}")

    @staticmethod
    def set_refrigeration(value: int):
        """半导体制冷片开关，0/1，命令：Refrigeration value"""
        return send_command(f"Refrigeration {value}")

    @staticmethod
    def set_fan1(value: int):
        """半导体制冷片风扇开关，范围0~255，命令：Fan1 value"""
        return send_command(f"Fan1 {value}")

    @staticmethod
    def set_duct_heater(value: int):
        """管道加热器开关，0/1，命令：DuctHeater value"""
        return send_command(f"DuctHeater {value}")

    @staticmethod
    def set_emergency_stop(value: int):
        """紧急停止开关，0/1，命令：EmergencyStop value"""
        return send_command(f"EmergencyStop {value}")

    @staticmethod
    def set_reactor_heater(value: int):
        """反应釜加热器开关，0/1，命令：ReactorHeater value"""
        return send_command(f"ReactorHeater {value}")

    @staticmethod
    def set_vacuum_pump(value: int):
        """真空泵开关，0/1，命令：VacuumPump value"""
        return send_command(f"VacuumPump {value}")

    @staticmethod
    def set_fan2(value: int):
        """超净台风机开关，0/1，命令：Fan2 value"""
        return send_command(f"Fan2 {value}")

    @staticmethod
    def set_uv_lamp(value: int):
        """紫外灯开关，0/1，命令：UV_lamp value"""
        return send_command(f"UV_lamp {value}")

    @staticmethod
    def set_lighting(value: int):
        """日光灯开关，0/1，命令：Lighting value"""
        return send_command(f"Lighting {value}")
        
    @staticmethod
    def get_temp_pump()->float:
        """ 获取co2泵温度 """
        return send_and_get("getTempPump 1")
    
    @staticmethod
    def get_temp_duct() -> float:
        """ 获取管道温度，命令：getTempDuct 1，返回：TempDuct value """
        return send_and_get("getTempDuct 1")

    @staticmethod
    def get_reactor_temp() -> float:
        """ 获取反应釜温度，命令：getReactorTemp 1，返回：TempReactor value """
        return send_and_get("getReactorTemp 1")

    @staticmethod
    def get_pump_pres() -> float:
        """ 获取反应釜压力，命令：getPumpPres，返回：PumpPres value """
        return send_and_get("getPumpPres")

    @staticmethod
    def get_traffic() -> float:
        """ 获取流量，命令：getTraffic 1，返回：Traffic value """
        return send_and_get("getTraffic 1")


if __name__ == "__main__":
    f = HardwareController()
    load_config()
    print(f.get_temp_pump())
